home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PsL Monthly 1993 December
/
PSL Monthly Shareware CD-ROM (December 1993).iso
/
prgmming
/
dos
/
pascal
/
pascalw.exe
/
lha
/
NIM.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1990-09-17
|
4KB
|
163 lines
Program Nim( input, output );
const
NROWS = 18;
var
i : integer;
key : char;
pile : array[1..3] of integer;
move : record
ntaken, pileno : integer;
end;
function GameOver : boolean;
begin
gameover := ( pile[1] + pile[2] + pile[3] = 0 );
end;
procedure display;
var
start, row, col : integer;
begin
ClrScr;
start := 0;
for col := 1 to 3 do
if pile[col] > start then
start := pile[col];
for row := start downto 1 do
begin
for col := 1 to 3 do
if pile[col] >= row then
write( ' __ ' )
else
write( ' ' );
writeln;
end;
if start > 0 then
writeln( pile[1]:4, pile[2]:6, pile[3]:6 );
writeln;
end;
procedure signon;
begin
writeln;
writeln( ' *** NIM *** ' );
writeln;
writeln( 'I will set up three piles of coins.' );
writeln( 'To move, take any number of coins away from any pile.' );
writeln( 'The player who clears the screen wins.' );
writeln;
write( 'Now hit any key to start:' );
while NOT keypressed do
;
key := readkey;
writeln;
end;
Procedure hismove;
var
ok : boolean;
begin
repeat
write( 'Pile (1,2 or 3)? ' );
readln( move.pileno );
ok := (move.pileno >= 1) AND (move.pileno <= 3);
if ok then
begin
write( 'Number to take away? ' );
readln( move.ntaken );
ok := (move.ntaken >= 1) AND (move.ntaken <= pile[move.pileno]);
end;
if not ok then writeln( 'What??' );
until ok;
pile[ move.pileno ] := pile[ move.pileno ] - move.ntaken;
end;
Procedure mymove;
var
firstbit, x, i, j : integer;
bit : array[1..3,1..4] of boolean;
parity : array[1..4] of boolean;
begin
for i := 1 to 3 do
begin
x := pile[i];
for j := 4 downto 1 do
begin
bit[i, j] := odd(x);
x := x div 2;
end;
end;
for i := 1 to 4 do
parity[i] := bit[1,i] <> (bit[2,i] <> bit[3,i]);
move.pileno := 1;
move.ntaken := 0;
if not ( parity[1] OR parity[2] OR parity[3] OR parity[4] ) then
begin
while pile[move.pileno] = 0 do
move.pileno := move.pileno + 1;
if pile[move.pileno] = 1 then
move.ntaken := 1
else
move.ntaken := random( pile[move.pileno]-1 ) + 1;
end
else
begin
firstbit := 1;
while not parity[firstbit] do
firstbit := firstbit + 1;
while not bit[move.pileno, firstbit] do
move.pileno := move.pileno + 1;
for i := firstbit to 4 do
begin
x := 1;
for j := 3 downto i do
x := x * 2;
if parity[i] then
if bit[move.pileno, i] then
move.ntaken := move.ntaken + x
else
move.ntaken := move.ntaken - x;
end;
end;
pile[move.pileno] := pile[move.pileno] - move.ntaken;
end;
Begin
Randomize;
Signon;
repeat
for i := 1 to 3 do pile[i] := random(10) + 6;
display;
repeat
hismove;
if gameover then
writeln( 'Congratulations ... You win!' )
else
begin
display;
Writeln( 'My move is ...' );
Delay( 1500 );
mymove;
display;
writeln( move.ntaken:3, ' from pile', move.pileno:2 );
if gameover then
writeln( '*** I win! ***' );
writeln;
end;
until gameover;
write( 'Another game? (y/n) ' );
repeat
key := readkey;
until (key = 'n') OR (key = 'y');
until key = 'n';
End.